class Socket {
  constructor (url, options = {}) {
    window.WebSocket = window.WebSocket || window.MozWebSocket
    if (!window.WebSocket) { // 检测浏览器支持
      console.error('错误: 浏览器不支持websocket')
      return
    }

    this.url = url
    this.socket = null
    this.options = {
      onOpen: options.onOpen || (() => {}),
      onMessage: options.onMessage || (() => {}),
      onClose: options.onClose || (() => {}),
      onError: options.onError || (() => {}),
      onReconnect: options.onReconnect || (() => {}),
      onFinished: options.onFinished || (() => {}),
      reconnect: options.reconnect || false,
      heartbeatInterval: options.heartbeatInterval || 5000, // 默认5秒
      heartbeatData: options.heartbeatData || 'ping',

      reconnectAttempts: options.reconnectAttempts || 3,
      reconnectDelay: options.reconnectDelay || 2000 // 默认2秒
    }

    this.reconnectCount = 0
    this.reconnectTimer = null // 重连timer

    this.lastHeartbeat = Date.now()

    this.hearbeatTimer = null
  }

  init () {
    if (this.url) {
      // 若不以wss?开头
      if (!/^wss?:\/\//.test(this.url)) {
        const { protocol } = window.location
        // 则自动补上协议头
        this.url = protocol === 'http:' ? 'ws://' + this.url : 'wss://' + this.url
      }

      if (this.websocket) {
        this.close()
      }
      this.websocket = new WebSocket(this.url)

      this.websocket.onopen = (e) => {
        console.log('连接成功', e)
        this.startHeartbeat()
        this.options.onOpen()
      }

      this.websocket.onmessage = (e) => {
        console.log('接收数据', e)
        this.options.onMessage(e.data)
      }

      this.websocket.onclose = (event) => {
        console.log('close')
        this.close()
        this.options.reconnect && this.reconnect()
        this.options.onClose()
      }

      this.websocket.onerror = (error) => {
        console.log('errorsss')
        this.close()
        this.options.reconnect && this.reconnect()
        this.options.onError(error)
      }
    }
  }
  send (message) {
    // readyState 1 表示已经链接并且可以通讯
    if (!this.websocket || this.websocket.readyState !== 1) {
      console.log('请确认websocket是否已经链接并且可以通讯')
      return
    }
    this.websocket.send(JSON.stringify(message))
  }

  close () {
    if (this.websocket) {
      this.websocket.close()
      this.websocket = null
      this.hearbeatTimer && clearInterval(this.hearbeatTimer)
      this.reconnectTimer && clearTimeout(this.reconnectTimer)
    }
  }

  reconnect () {
    if (this.reconnectCount < this.options.reconnectAttempts) {
      const _this = this
      this.reconnectCount++
      this.options.onReconnect()
      this.reconnectTimer = setTimeout(() => {
        _this.init()
      }, this.options.reconnectDelay)
    } else {
      this.options.onFinished()
    }
  }

  startHeartbeat () {
    const _this = this
    this.hearbeatTimer = setInterval(() => {
      _this.send(_this.options.hearbeatData)
    }, this.options.heartbeatInterval)
  }
}

export default Socket
